package velox.jcr.mapper;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;

import velox.jcr.util.NodeUtils;


public class CollectionPersister {
	public static void writeCollection(List<?> list, Node node,
			boolean create, String containerName, CascadeType cascade,
			Mapper mapper) throws RepositoryException {
		NodeUtils.assertChild(node, containerName);
		
		MapperManager manager = UnitOfWorkHolder.get().getMapperManager();
		
		NodeRef container = new NodeRef(node.getNode(containerName));
		if (create && cascade.isPersist()) {
			for (Object e : list) {
				String shortName = mapper.getName(e);
				manager.persist(container, shortName, e);
			} 
		} else {
			if (list instanceof PersistentCollection && ! ((PersistentCollection) list).isLoaded()) return;


			if (cascade.isPersist()) {
				Set<String> ids = new HashSet<String>();

				for (PersistentCollection.Entry entry : ((PersistentCollection) list).getChangeLog()) {
					if (entry.getOperation() == PersistentCollection.Entry.Operation.REMOVE) {
						ids.add(mapper.getId(entry.getEntity()));
					}
				}
				
				// Remove all nodes found in the list
				NodeIterator ni = container.getNode().getNodes();
				while (ni.hasNext()) {
					Node n = ni.nextNode();
					if (ids.contains(n.getUUID())) {
						n.remove();
					}
				}

				// TODO: Handle moved entities
				for (Object o : list) {
					String id = mapper.getId(o);
					if (id == null) {
						String shortName = mapper.getName(o);
						manager.persist(container, shortName, o);
					} else if (id != null) {
						// Check if in correct place
						Node p = manager.getSession().getNodeByUUID(id);
						if (! p.getParent().isSame(container.getNode())) {
							manager.getSession().move(p.getPath(), container.getNode().getPath() + "/" + mapper.getName(o));
						}
						
						manager.update(o);
					}
				}
			}
		}
	}

}
